#pragma once

#include "../Core/Matrices.h"
#include "../Core/RealSquareMatrices.h"
#include "../Core/TensorProductSurfaces3.h"

namespace cagd
{
    class TrigonometricBernsteinSurface3: public TensorProductSurface3
    {
    protected:

        // shape parameters in directions u and v, respectively
        GLdouble            _alpha, _beta;

        // orders of basis functions in directions u and v, respectively
        GLuint              _n, _m;

        // normalizing coefficients in directions u and v, respectively
        RowMatrix<GLdouble> _u_c, _v_c;

        // binomial coefficients
        RealSquareMatrix    _bc;

        // auxiliar protected methods
        GLvoid              _CalculateBinomialCoefficients(GLuint order, RealSquareMatrix &bc);
        GLboolean           _CalculateNormalizingCoefficients(GLuint order, GLdouble alpha, RowMatrix<GLdouble> &c);

    public:
        // special constructor
        TrigonometricBernsteinSurface3(
                GLdouble alpha, GLuint n,
                GLdouble beta, GLuint m);

        // inherited pure virtual abstract methods that must be redeclared and defined
        GLboolean UBlendingFunctionValues(GLdouble u, RowMatrix<GLdouble>& values) const;
        GLboolean VBlendingFunctionValues(GLdouble v, RowMatrix<GLdouble>& values) const;
        GLboolean CalculatePartialDerivatives(GLdouble u, GLdouble v, PartialDerivatives& pd) const;

        // calculates the area of the surface
        GLdouble Area(GLuint u_div, GLuint v_div) const;
    };
}
